現役Lisperが語る! Lispはオーパーツで人類には早すぎた【電脳史学】
HTML-код
- Опубликовано: 28 июл 2024
- "LISP" はオーパーツなんですよ。
原初の言語にして現代でも色褪せないポテンシャル。ガーベジコレクションを最初に採用した言語で後のプログラミング言語にも多くの影響をあたえている。Lispのコードはリストなんですよ。コード=データなわけ。全部をリストに入れられるんです。もちろん関数も入れられる。二分木で表現されていてリスト操作もシンプル。ただ当時の計算機リソースではポテンシャルを発揮できず、登場する時代が早すぎた。大学の教科にもなるくらいシンプルで応用の効く言語で、関数型言語的な書き方にも相性がよいです。そうそう、プログラミング言語には遠心力と求心力があってね。人口の多い言語は成長して求心力・引力が発生しますが、そのうちその言語が嫌だという遠心力が生まれて新しい言語の発見に繋がります・・・
■ゆる学徒ハウス別館ANNEXとは?
sites.google.com/view/yurugak...
メンバーがそれぞれ得意分野を持つ蘊蓄、雑学大好き集団。
始まりはゆる言語学ラジオのオーディション企画、「ゆる学徒ハウス」。挑戦した中で落選するも、「語りたりない」者たちが集まって立ち上げたチャンネルです。
知的にふざけながら、興味深い動画を発信していきます。
主に対話型のラジオ形式コンテンツを投稿してます!
※収録環境が未だ手探りなため、音声や画像の質が悪い場合があります。ご了承ください。
また、本コンテンツは学徒たちの手作りで運営しているため、本家様ほどのクオリティは出せないかもしれません。
ご意見、ご指摘、ご感想はコメント欄かこちらのフォームよりお願いいたします。
■おたよりフォーム
forms.gle/TgH8CQzU4bRerZCz5
※最善を尽くしていますが、個人名を指定してのご質問やご要望には対応できない場合もあります。ご了承ください。
■本家「ゆる言語学ラジオ」
/ @yurugengo
■ゆる学徒ハウス (本館)
/ @yurugakuto
【BGM提供】
・フリーBGM・音楽素材MusMus様 musmus.main.jp/
【目次】
0:00 Lispの話をするよー
2:44 Lispはリスト形式だぞー
10:25 Lispの歴史上の立ち位置
23:37 マクロの話
27:07 バグからわかる関数型言語の面白さ
34:35 Lispはなぜ繁栄しなかった?
38:35 Lispでの設計の流れ
47:13 どの言語にも文化がある
49:10 言語の栄枯盛衰
1:01:31 選べる余裕が多様性を生んだ
1:07:18 実装回に向けて
1:10:50 Lisp信者に刺されたくない弁明
1:15:45 エンディング Наука
41:33 「世界全体を表すデータをまず最初に定義しますね」
ここカッコいい…
文字で見るとなんか凄いこと言ってますね… 笑
スミノさんの話わかりやすかった!
あまり躊躇せず高度なこと好きなように話してほしい。。!
ありがとうございます!今後のLisp回ではもっとギアあげていきます!
聞き手の方のリスナーへの配慮が行き届いていてわかりやすかった。
ありがとうございます。聞き手のマダカさんのおかげで僕も気持ちよく話せました。
(雑な言い方だけど)オブジェクト指向の便利なところは…、
”きちんとした”ライブラリが提供されれば、そのライブラりの対象をリモコン感覚で操作できる。
(更にリモコンの作りが共通化されていれば、たとえば、電源ボタン→プレイボタン… をスタート操作として共通化できる)
また、対象の機能、属性の”付け足し”ができる(積極的にお勧めはしないけど)。
リモコンは良いメタファーですね。とてもわかりやすいです。
僕は以前の動画(ゆる学徒リベンジ#1)で「電子レンジ」になぞらえたことがありました。ユーザはインターフェイス越しで利用し、内部状態(温度や電力)は見ることができないという例えでした。
門外漢にも面白かったです〜😊
お2人の声が聞き心地良くてあっという間の1時間超でした
来月からのAI月間も楽しみにしてます😊
ありがとうございます。マダカさんが上手に補足してくれるのでのびのびと話せました。
24:40 関数とマクロの大きな違いは、関数は予め引数を評価してから関数に渡すのに対して、マクロは引数を評価せずにリストの儘マクロに渡すことです。
例えばフィボナッチ数列を出すプログラムがあるとして、終了条件 (< n 10) を変えて実行したいとする。関数なら条件を評価して T か NIL が関数に渡るので期待する動作にならない。マクロなら条件そのものが渡され、実行時に条件を評価できる。
その説明だと26:42で言及されているように高階関数との違いが伝わらないように思います。
lispは書いたことないのであれですが、処理ではなくコードそのものを渡すことでしたいことに対して柔軟に使いまわせるイメージです
すばらしい補足をありがとうございます。
動画にするときは原理原則をどこまで説明すべきか迷いますね。
マクロに関してはC言語やってる人からしたらだいぶ馴染み深いはず。#defineはマクロそのものだし、その他のプリプロセッサも語弊を恐れず言えばある種のマクロとも言える。
平たく言うとソースコードに対する操作をソースコード上に書けるのがマクロ。
マンデルブロ集合を描くプログラムをいくつかの言語で書いてみるという事をやってみたことがありますが、Lispが一番シンプルに書けました。末尾再帰が優秀。
初めて末尾再帰最適化を知ったときに感動したのを覚えています。LispやHaskellはマンデルブロ集合の描画がとてもシンブルに書けますよね。
約40年前、Lispでシステム組んで卒論書いたんですが
内容もLispもすっかり忘れました。
car, cdr , 再帰 とかを聞いて
あーそんなのあったなー、と
とても懐かしくなりました。
CPU は86系がいいか、68系がいいか
と争われていた時期です。
ご視聴ありがとうございます。大先輩ですね!
CPUの話題では僕が学生の頃には"CISC 対 RISC"の話題がホットでした。近年再びRISCが台頭してきて「やっときた・・・!」といった感慨があります。
@@smnkyRISC-Vが一番好きです
俺「Lisp完全に理解した。」
Lispの"絶望の谷"は浅いので安心して進んでください 笑
触れられているようにLispでもオブジェクト指向が提供されていることがあります。
Lispのオブジェクト指向は引数の型による多重ディパッチで実現されます。
いわゆるOOP言語のメソッドは第1引数がthisに固定された単一ディスパッチに過ぎない、
多重ディスパッチはそれよりもっと自由度が高くて、方法論としては関数型的側面も強いなぁと目から鱗が落ちた思い出があります。
僕も多重ディスパッチ(マルチメソッド)を最初に経験したときには感動しました。いまでも多相を扱うときには型クラスよりマルチメソッドの方を好んで使います。
ゆる言語学ラジオの関連動画で出てきたので見始めたがイケボで草
説得力のあるいい声ですね
業務でオブジェクト指向言語扱ってますけど、オブジェクト指向で作られたフレームワークを使いながらも、データとロジックを分離しロジック部は手続き型だったり時には関数型っぽく書きます。業務ロジックをオブジェクト指向で書こうとするとこの動画で言及されていたような問題がでてくるので。オブジェクト指向言語を使ってる理由はオブジェクト指向で作られたフレームワーク(ORMやUI関連)を便利に扱えるからですかね。
なるほどそうなのですね。
関数型言語でも部分的にオブジェクト思考っぽく書く場合があります。
おっしゃるとおりORMやGUIなどはオブジェクト指向がフィットしますね。
「えぇ!Lispできるの!?」って言おうと思ったけど、スミノさんだと違和感が無いです!!
自分はメインエディタがEmacsだった頃に泣きながら覚えて、他のエディタに乗り換えたときにすっかり忘れましたw
Lispは癖が強いので好みがわかれますよね。僕もプログラマー仲間にはあまり勧めてないです 笑
12:49 ガベージコレクションの例えを出すときに、「アプリを落とした後に手動でメモリ開放の操作をしなくてもよい」という例えをしようとしたけれど、「しばらくアプリを使わないとメモリを勝手に開放している」という例えに切り替えたのかなと言う深読み
僕も同じような深読みをしてました 笑
非プログラマにも分かり良いメタファーってなかなか思いつかないですよね。
大昔、雑誌に掲載されていたZ80のアセンブル言語でかかれたlispインタープリタが、本質的には中西 正和「Lisp入門」にあったevalの動作そのものだったのをみて、そのスマートさに驚いた記憶があります(lispでlisp処理系を書くことを実感しました)。あとはscheme R5RSのコンパクトさは印象的でした。
雑誌で中西正和さんの連載を読んだ記憶があります。僕もパソコン雑誌で初めてLispに触れました。当時はシンプルなものしか実装できませんでしたが、そのパラダイムの自由さと強力さにインパクトを受けました。
プログラム全く分からない者ですが、関数型言語の凄さを感じました。
世界が不変的で、その外で無数の変数を用意するのがオブジェクト指向なら
世界の中に変数を用意し、世界自体が変わっていくのが関数型
の様な印象を受けました。
ありがとうございます。プログラマではない方にも伝わったのでしたら動画としては大成功です!
(ざっくり言うと)個々のオブジェクトがパラメータを保持しているのがオブジェクト指向で、パラメータを外部化して関数へ入力値として渡すのが関数型ですね。
またタイトルだけで絶対おもしろいやつ来たw
ありがとうございます!
僕もこのタイトルとサムネが出てきたら秒でクリックします 笑
ダグラス.H.ホフスタッターという入子構造オタクが「Lispは面白い」と事あるごとに本に著述してて、なかなかプログラムに馴染みがないからいつか分かればいいやと読み飛ばしていたんですがこの動画でやっとホフスタッターが面白がっていた意味が分かった気がした
入れ子といえば再帰もそうですが、Lisp特有の「マクロを構築するマクロを構築するマクロ・・・」が書ける自由さが面白いと思います。まさにメタプログラミング。
Lisp未経験ですが、型無しλ計算そのままのイメージですね。完全に理論先行だからこそ今でも生き残っているのが面白い…
まさにラムダ計算の理論をベースにしてつくられた言語ですね。さらにマクロを組み込んだことにより現在でも通用するポテンシャルを発揮しています。
54:05 EdgeはChromiumなので実質Chromeです(過激派)
たしかに!純血を守っているブラウザって少ないですね。
データとプログラムを同じリストに並べて扱うというのは、むしろノイマン型コンピュータの設計そのものではないでしょうか?
ほんとですね。機械語のアドレッシングの自由さを理論でうまくラップした感じにでしょうか。高級言語では珍しい特性だと思います。
Lispはどこで使われているのか?
という問いに対してですが、
まず開発者にとって一番身近なlispの一つがemacs lispな気がします。
また最近の多くの言語のastや高級寄りの中間表現はlispのコードみたいだなと思っています。
現代の多くの言語はコードの見た目は違っても、直接的・間接的にlispの影響を受けている気がします。
近年ではルンバ(ロボット掃除機)のアルゴリズムがLispで実装されていたと聞いたことがあります。
言語のAST実装などはLispやHaskellなどの抽象化力の高い言語がフィットしますね。Lispは後の言語にたくさんの影響を与えていると思います。
プログラミングの宗教論は
きのこたけのこ戦争程度に捉えるのがいいですね…
ちなみに私はたけのこ派です
僕はきのこ派です!
マイノリティであり続けることには慣れてます。Lisperですから 笑
左のおじさんの話をもっと聞きたい!
ありがとうございます!もっと動画出します。
clojureのコミュニティルールを型レベルで強制するのがHaskellのモナド(のIO型クラス)ですかねー
副作用をどの程度分離するかをプログラマにまかせているClojureの方が僕は使い良いですねー。Haskellではいつもコンパイラに叱られてます 笑
3:00 アトムは数値と文字列とNILと後シンボルですね
ご指摘ありがとうございます。シンボルがないと何も定義できないですね…。
nilは独立したデータ型ではなく、ただのシンボルのうちのnilというものを特別扱いしてるだけです。
ヤベー、ムズすぎる。
華麗に出ってくる専門用語が
カッコいい。
イヤ~いいすね。
俄には出せない専門性が素敵すぎる。
ありがとうございます!
マダカさんが噛み砕いてくれているので、なんとかこの程度に収まりました 汗
Lispの大まかなイメージとして、ポーランド記法のおばけだ!という理解でいいのかしら🥺
リスト構造のhead部分がその後に連なるリストの演算子のようなものだ、と考えると、数学で関数表記が入れ子になってるf(x, g(y, z))みたいな感覚と近いのかな?
手続き型に慣れちゃってるので、かっこまみれで可読性どないやねん!!ってなりそうですけど、それこそ適切にインデントすればいいだけだし、Pythonみたいにかっこじゃなくてインデントでリストを表しましょう!みたいな方言があってもおかしくなさそうですね~。
初めの10分だけでもかなり妄想が捗りますな・・・
そのとおりです。
ポーランド記法のおばけ→Lisp、逆ポーランド記法のおばけ→Forth
LispはIDEが「Lisp式インデント」をしてくれるので、その視覚的なブロックで構造を判断します。(8:30)
ほとんどのLisperは括弧を「見ていません」。 ")))))))" は大きいブロックの終わりを表す記号くらいに思っています 笑
@@smnky わぁ!ご返信ありがとうございます!!
そっかぁ・・・IDEがあるから閉じかっこはええ感じに閉じてくれるんですかねぇ。。。
IDEちゃんがいない頃は閉じカッコ数えてたんだろうなぁ・・・(遠い目)
@@matanki153cm IDEのサポート無しでLispを書くのは拷問ですね。
Lisp式インデントや括弧の操作に対応しているエディタが必要です。
なんか機械語みたいな感じですかね?関数も数値もHEXみたいな。高専でClispの単位を落としたFPGA屋にはむずいですが、学生時代を思い出しました。ありがとうございます。
実行コードが書いているアドレスの数値(=コード)自分で書き換えられるという点では似ていると思います。
自分がLispを勉強した当時は動かせる環境がなかったですねえ。Unixの仮想記憶環境がメジャーになってから身近になった印象。Kyoto-Lispがあるのは知ってた位のもの。
Fortran77は大学のセンターで、CはBDS-CやLSI-Cで何とか動かせた、結局一番便利だったのはIDE環境が整ってたTurboPascalとN98-BASICだったというオチw
当時Lispは贅沢な言語でしたよね。僕も本格的に使うようになったのはUnix機からです。
Lispにおけるリストとは片方向リスト(単方向連結リスト)です、と用語を使ったほうが説明しやすいと思います。
あとデータもコードもリストで表しますよ、と言ったときにevalという概念を導入した方がマクロを説明しやすいですね。
おっしゃるとおりですね。
どの部分まで踏み込んで説明すべきかを明確に決めきれてなかったと反省してます。
片方向リストは図を見せたほうがわかり良かったですよね。次回に活かします。ありがとうございました。
…「マクロ」はややこしい。おそらく複数の処理をひとまとめになっているのを、「マクロ 」と称している…と思うけど^^;
例えば…キーボード マクロだと1つの(ショートカット)キー操作で定義した複数の処理ができる。
Excelのマクロだと「…指定された文字列を探して色を赤にする(探索と文字色変更などの複数の処理)」を一纏めに。
C言語でプリプロセッサにやらせる… 置き換え(MY_ABC(x) と書くと abc("c:\users\work\", x, "rw") に展開しろ!みたいな)
プログラミングで使われている用語は、言語ごとに意味する範囲が異なったりして混乱しますね。
「ある程度の処理をひとまとめにして名前をつけたもの」といったニュアンスは共通かもしれません。
Lispのように「マクロを定義するマクロを定義するマクロ・・・」とできるのがマクロで、ブリプロセッサ的なものはテンプレート・・・? 定義が曖昧でややこしいですよね。
なぜ流行った分からない言語、Goがまっさきに浮かびました()
実は僕もそう思ってました 笑
最近実務で触ることがあったのですが、意外と使い心地は悪くなかったです。
他人の書いたコードでも読みやすく、なによりコンパイルが速い。
LispのマクロはC言語のマクロと基本的には同じかな? コンパイル前に文字列を置き換える機能。
メタプログラミングという面では多言語のマクロや(Haskellなどの)テンプレートと似ています。
ただ、マクロの引数によって生成するコードを変えたりループしたりとやりたい放題なのがLispのマクロの特徴ですね。
純粋関数型言語(Ocaml)が楽しかったのでlispも楽しいに違いない。
僕はOcamlは趣味で触った程度ですが楽しいですよね。とてもバランスの良い言語だと感じました。
OCamlは副作用を認めているので純粋ではない関数型言語ですね。
純粋関数型はHaskellやCleanになります。
@@miner1227 副作用OKなんですね、知りませんでした。
素人の疑問なのですが、ゲームの例えであった、再帰でループしてレンダリングした場合、スタックオーバーフローになるんじゃないか疑問に思いました。
すばらしい質問です!おっしゃるとおり再帰でループするとスタックを食いつぶすのですが、ほとんどの関数型言語の処理系には「末尾再帰最適化」という仕組みがそなわっており、式の末尾が再帰になっている場合は内部でループ処理に変換されます。これによりスタックの消費量は1に抑えられます。
@@smnky ありがとうございます❗️ モヤモヤしていた疑問がスッキリしました😊
素朴なプロトタイプベースから、見かけ上クラスベースまで、様々なオブジェクト指向のやり方ができて、さらに関数型チックにも書ける。
非常に柔軟であり、かつコミュニティによってこう書くべきという縛りも殆ど存在しない。
更に処理系が超爆速なJavaScriptが間違いなく最強の言語ですよ。
Javascriptエンジン(v8等)は他のスクリプト言語と比較しても性能が高く、言語としての求心力(とそれによる開発リソースの集中)を感じます。言語仕様として暗黙的な型変換がなければもっと良かったのですが。
全く違うかもしれませんが、
バグの処理はいわゆるmonadの話なんですかね。
値にmonadoつけることで状態も付加しておくみたいな
(何度勉強してもあんまりよくわからない...)
モナドを利用するのもひとつの方法ですね。
状態をグローバル変数やオブジェクトの内部状態にせずに、必要な状態をまとめたデータセットを関数に引き回すことにより参照透過性を高めるといった感じですね。
@@smnky
お返事ありがとうございます!
参照透過性、よく聞くのですが実際にコーディングしないとなかなか想像がつかないです😖(主にfortranとpythonくらいしか使ったことない)。Lispで実用的なコード書ける人ほんとにすごい
@@kotokoto8362 脳のクセと慣れですね。僕は逆にオブジェクト指向で巨大なコードを書くのが苦手ですよ。
実際にコーディングしないとその言語の特徴が想像しづらいというのは本当にそのとおりだと思います。
@@smnky 本見てちょっとだけLisp動かしてみたのですが、数学・論理学の問題解いてる気分です😅ゆっくりですが少しずつ書いてみます
いにしえのニコニコ動画上でスクリプト言語を使ってLispが動作するようにようにしているユーザがいたのを思い出しました😁
なんと!それは知りませんでした。情報ありがとうございます!
ニコニコがFlashで動いていた頃はニワン語という仕組みでスクリプトが書けたのですが、2017年から動画プレイヤーがHTML5に移行されて2020年に完全終了しました。ニワン語でLispを実装していた方は2名ほどいらしたのですが、そのうちの一人のzickさんは40個以上の言語でLispを実装しています。(ZickStandardLispを参照)
@@nyandarswan 何かにつけてニートになりたがる、リリカル☆Lispの開発者....
@@nyandarswan 「ニワン語」ってネーミングが洒落てますね。
ZickStandardLispで検索しました。まさに「Lispはどの言語上にでも簡単に構築できる」を証明されている方ですね。すばらしい!
括弧の数に辟易しない人間がいることが信じられない。
Lisperはエディタ画面上の括弧をほとんど意識していないと思ってます。
8:30 のコードが良い例ですが、インデントによる視覚的なブロックで構造を判断しています。
この話はまた別の動画で説明しますね。
括弧の種類が少ない&位置が独特なだけで、数としては言うほど多くないという話もあるかもです。たとえば、よくある C 系言語の `if (cond) { foo(); bar(); }` は、よくある lisp 系言語だと `(when cond (foo) (bar))` ですが、特に括弧は増えてなかったりします(むしろ実は減ってるし、ちゃっかりセミコロンも省略できてたりする)
@@zk_phiうーん。Cのif文はif (条件){文}else{文}なので()は一つですよね。{}も括弧だと言えばそうですけどそれは最初に私が書き足りなかったですね。宣言型と手続き型の言語を比較しても仕方がないので関数型をやるならHaskellではなかろうかと思うのです 。私はビジネス系開発が多かったので「ハッカーと画家」に書いてあることが全く理解できなかった。というかピンとこなかった。ライバルがLispプログラマーを集めていることやそもそもLispプロジェクトが動いているところを見たことがありません。でも世の中は広いなあ。現にそういう方がいるとは。
Lisp以外のプログラミング言語はlispになりたがっている?
Lispの持つ特徴やコーディングスタイルが見直されているなら嬉しいですね。
かー、って予約語はあって、これ、カラスか徳島県民の言語かって思ったことはある
ちなみに、徳島県民の方言で「かー」は「ちょうだい」って、意味になる。
耳がフリーズしました
「ケガレ」とかは聞こえたのでいろんな言語で使う「方言」?を教えてください
何か見えてくるものがあるかも
「穢れ」は以前の動画で僕が勝手に例えた比喩ですね。一般的ではないかも。
「純粋ではない(副作用を含む)関数を呼び出す関数もまた純粋ではなくなる」というのを「穢れがうつる」という表現に例えました。
他にもプログラミング独自の例えや用語はありそうですね。調べてみます。
助かった
ご視聴ありがとうございます。
Lispを知らない方に説明する時のもどかしさが(^^;; マクロの説明は、メタなプログラミングができる、簡単なものだとC言語のマクロやC++のテンプレートみたいなことや、条件分岐やループみたいな制御構造も独自なものに変えられるし、関数定義のdefne的なものも独自にできたり、関数の実行構造そのものをその場に合わせてプログラムで変えたり・生成したりもできる、・・・・・・みたいに説明してはどうでしょうか。
ご助言ありがとうございます。
たしかにメタプログラミングの概念は他の言語にもありますものね。(Ruby on Rails もマクロを多用していますし)
次のLisp回の参考にさせていただきます!
@@smnky あるものごとを、仕組みで語るか(全てがリストになっていることと、評価タイミングを制御できること)、効果で語るか(今回の提案)、理論で語るか(特にLispは!)は悩ましいところですね。わたしは、効果で語って、その背景となっている仕組みの片鱗を語るのが腑に落ちやすいのでは、と思いました。
@@user-of5nb2gi9s そうですね。「それがあると何が嬉しいのか」「他の言語のマクロ(テンプレート)と比べてどう違うのか」「なぜそうなのか(技術背景)」のようにメリット→理論だと聞き手にも興味を持続してもらえそうです。ありがとうございます!
マジか。私30代前半なんですが、デフラグが少し説明しないと通じないのはちょっとショックだw今の10代とか20代前半にMDとかHVSとかLDとか伝わらないみたいなw
もういまの若者は「巻き戻しボタン」とか知らないですからねー。説明に使うメタファーを定期的に見直さないと通じなくなっちゃいますね。
やったスミノさん回👏👏😭
ありがとうございます。3月公開予定のAIシリーズにもいろいろ出演してます!
サムネイルのメガネに反射してるキャラって、LISPのマスコットキャラですか?
おめめが沢山ある!
プログラミング言語のマスコットキャラが総じてキモキモのキモなのは何でなんですかスミノ氏!
ゆるコンピューター科学ラジオでのオライリー書の紹介部分にのっかってるんだと思います。
あのマスコット "Lisp Alien" は書籍"Land of Lisp"の作者が生みの親です。
「他言語プログラマから見たLisper」のイメージだそうです。
公式ロゴではありませんが、いまでは公式ロゴよりも有名だと思います 笑
6:00 LISPは自己増殖系言語の代表格ですね。実行時にどんどんプログラムを拡張する事ができる。
自分用にDSLを書いているような感覚ですね。
ガベコレをブラウザのメモリセーバーの機能で例えるのは違いますね
同じなのはメモリの消費を抑えるという目的だけで働きも条件も全く異なる
Javaが流行った理由は至極簡単だと思う。当時最もモダンな高級言語、C/C++の流れに乗った言語だったから。C言語、C++、Java、C#などの流れは断続的で。今ある知的資源、物流資源、ソフト資源、あらゆる資源をどれだけ有効活用出来るかは大事。いくら5Gが優れて居ても、基地局やバックボーン、端末の置き換えの課題が大きく。だからLTEが3.9として大変大きな役割があったのです。それと同じかと。C#なんてパラダイムで見たら、構造化、オブジェクト指向、VM型、関数閉包、ラムダ式などなど、ほんとちゃんぽんですから。